package top.lv666.graduation_design_serve.service;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.vdurmont.emoji.EmojiParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.lv666.graduation_design_serve.mapper.BlogMapper;
import top.lv666.graduation_design_serve.mapper.TopicMapper;
import top.lv666.graduation_design_serve.mapper.UserInfoMapper;
import top.lv666.graduation_design_serve.pojo.*;
import top.lv666.graduation_design_serve.util.JWTUtils;
import top.lv666.graduation_design_serve.util.Tools;

import javax.servlet.http.HttpServletRequest;
import javax.tools.Tool;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class BlogServiceImpl implements BlogService {
    @Autowired
    private BlogMapper blogMapper;
    @Autowired
    private TopicMapper topicMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    //避免变量重复声明，节约性能
    private Map<String, Object> parmMap = new HashMap<>();

    /**
     * 我关注的用户发布的博客
     */
    @Override
    public List<Blog> SelectMyFouceBlog(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        Tools.isLogin(request);
        String id = Tools.getUserId(request);
        map.put("userId", id);
        int getPage = (int) map.get("getPage");
        getPage = (getPage - 1) * (int) map.get("getNumber");
        map.put("getPage", getPage);
        List<Blog> blogList = blogMapper.SelectMyFocusBlog(map);
        if (request.getHeader("Authorization") != null && !(request.getHeader("Authorization").equals(""))) {
            parmMap.clear();
            parmMap.put("userId", Tools.getUserId(request));
            // 查询该用户点赞的博文
            List<BlogLike> likeInfo = blogMapper.SelectUserIsLike(parmMap);
            // 查询该用户的转发博文
            List<BlogRef> blogRefs = blogMapper.SelectBlogRef(parmMap);
            // 查询用户的关注列表
            List<Attention> attentions = blogMapper.SelectAttention(parmMap);
            return Tools.isBlogOpt(request, blogList, likeInfo, blogRefs, attentions);
        } else {
            return Tools.isBlogOpt(request, blogList);
        }
    }

    /**
     * @apiNote 我点赞的博客
     */
    @Override
    public List<Blog> SelectMyLikeBlog(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        Tools.isLogin(request);
        String id = Tools.getUserId(request);
        map.put("userId", id);
        int getPage = (int) map.get("getPage");
        getPage = (getPage - 1) * (int) map.get("getNumber");
        map.put("getPage", getPage);
        List<BlogLike> blogLike = blogMapper.SelectMyLikeBlog(map);
        List<Blog> blogList = new ArrayList<>();
        for (BlogLike b : blogLike) {
            Blog blog = blogMapper.SelectBlog(b.getBlogId());
            blog.setUserInfo(userInfoMapper.queryLoginUserById(blog.getUserID()));
            blogList.add(blog);
        }
        if (request.getHeader("Authorization") != null && !(request.getHeader("Authorization").equals(""))) {
            parmMap.clear();
            parmMap.put("userId", Tools.getUserId(request));
            // 查询该用户点赞的博文
            List<BlogLike> likeInfo = blogMapper.SelectUserIsLike(parmMap);
            // 查询该用户的转发博文
            List<BlogRef> blogRefs = blogMapper.SelectBlogRef(parmMap);
            // 查询用户的关注列表
            List<Attention> attentions = blogMapper.SelectAttention(parmMap);
            return Tools.isBlogOpt(request, blogList, likeInfo, blogRefs, attentions);
        } else {
            return Tools.isBlogOpt(request, blogList);
        }
    }

    /**
     * @apiNote 删除博客
     */
    @Override
    public void DeleteBlog(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        Tools.isLogin(request);
        String blogID = (String) map.get("blogId");
        String userId = (String) Tools.getUserId(request);
        Blog blog = blogMapper.SelectBlog(blogID);

        if (blog.getUserID().equals(userId)) {
            map.put("deleteTime", Tools.getTime());
            blogMapper.DeleteBlogById(map);
            if (!blog.getBlogTitle().equals("")) {
                Topic topic = topicMapper.getTopicById(blog.getBlogTitle());
                int seeNumber = topic.getSeeNumber();
                double topiceNumber = topic.getTopicNumber();
                String createTime = topic.getCreateTime();
                double searchNumber = topic.getSearchNumber();
                int num = topic.getTopicNumber();
                if (num == 1) {
                    num = 2;
                }
                parmMap.clear();
                parmMap.put("id", blog.getBlogTitle());
                parmMap.put("topicNumber", --num);
                parmMap.put("hotSearch", Tools.getHotSearch(searchNumber, seeNumber, topiceNumber, createTime));
                topicMapper.modifyTopic(parmMap);
            }
        } else {
            throw new Error("操作ID不符！！！");
        }
    }

    /**
     * @apiNote 查询当前用户下的博文
     */
    @Override
    public List<Blog> SelectBlogByUser(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        Tools.isLogin(request);
        String id = Tools.getUserId(request);
        map.put("id", id);
        int getPage = (int) map.get("getPage");
        getPage = (getPage - 1) * (int) map.get("getNumber");
        map.put("getPage", getPage);

        // 获取返回博文数组
        List<Blog> blogList = blogMapper.SelectBlogByUser(map);
        if (request.getHeader("Authorization") != null && !(request.getHeader("Authorization").equals(""))) {
            parmMap.clear();
            parmMap.put("userId", Tools.getUserId(request));
            // 查询该用户点赞的博文
            List<BlogLike> likeInfo = blogMapper.SelectUserIsLike(parmMap);
            // 查询该用户的转发博文
            List<BlogRef> blogRefs = blogMapper.SelectBlogRef(parmMap);
            // 查询用户的关注列表
            List<Attention> attentions = blogMapper.SelectAttention(parmMap);
            return Tools.isBlogOpt(request, blogList, likeInfo, blogRefs, attentions);
        } else {
            return Tools.isBlogOpt(request, blogList);
        }

    }

    /**
     * @apiNote 查询当前用户下的博文
     */
    @Override
    public List<Blog> SelectBlogByUserId(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");

        int getPage = (int) map.get("getPage");
        getPage = (getPage - 1) * (int) map.get("getNumber");
        map.put("getPage", getPage);

        List<Blog> blogList = blogMapper.SelectBlogByUser(map);
        parmMap.clear();

        if (request.getHeader("Authorization") != null && !(request.getHeader("Authorization").equals(""))) {
            //设置当前的操作用户
            parmMap.put("userId", Tools.getUserId(request));
            // 查询该用户点赞的博文
            List<BlogLike> likeInfo = blogMapper.SelectUserIsLike(parmMap);
            // 查询该用户的转发博文
            List<BlogRef> blogRefs = blogMapper.SelectBlogRef(parmMap);
            // 查询用户的关注列表
            List<Attention> attentions = blogMapper.SelectAttention(parmMap);
            return Tools.isBlogOpt(Tools.getUserId(request), blogList, likeInfo, blogRefs, attentions);
        } else {
            return Tools.isBlogOpt(request, blogList);
        }
    }

    /**
     * @apiNote 创建新博客
     */
    @Override
    public void CreateBolg(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        //生成该文章的唯一ID
        String blogID = Tools.getUUID();
        String token = request.getHeader("Authorization");
        if (JWTUtils.verify(token)) {
            //解析Token加密数据
            DecodedJWT jwt = JWTUtils.getTokenInfo(token);
            //获取uID
            String uId = jwt.getClaims().get("uId").asString();
            map.put("blogID", blogID);
            map.put("userID", uId);
            map.put("blogContent", EmojiParser.parseToAliases((String) map.get("blogContent")));
            map.put("blogUpTime", Tools.getTime());
            //数据库commit
            blogMapper.CreateBlog(map);
        }
        if (map.get("blogTitle") != null) {
            String id = (String) map.get("blogTitle");
            Topic topic = topicMapper.getTopicById(id);
            int number = topic.getTopicNumber();
            int seeNumber = topic.getSeeNumber();
            double topiceNumber = topic.getTopicNumber();
            String createTime = topic.getCreateTime();
            double searchNumber = topic.getSearchNumber();
            parmMap.clear();
            parmMap.put("topicNumber", ++number);
            parmMap.put("id", id);
            parmMap.put("hotSearch", Tools.getHotSearch(searchNumber, seeNumber, topiceNumber, createTime));
            topicMapper.modifyTopic(parmMap);
        }


    }

    /**
     * @apiNote 更新博客信息
     */
    @Override
    public void UpdateBlog(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        Tools.isLogin(request);

        // API设计问题需要兼容处理
        String blogID = "";
        if (map.get("blogId") != null) {
            blogID = (String) map.get("blogId");
            map.put("blogID", blogID);
        } else {
            blogID = (String) map.get("blogID");
        }
        //查询博客ID合法性
        Blog blog = blogMapper.SelectBlog(blogID);
        if (blog == null) {
            throw new Error("无效blogId！");
        }

        // 计算热度
        double likeNumber = 0;
        double commNumber = 0;
        double forwardNumber = 0;
        if (map.get("likeNumber") != null) {
            likeNumber = (int) map.get("likeNumber");
        } else {
            likeNumber = blog.getLikeNumber();
        }
        if (map.get("commNumber") != null) {
            commNumber = (int) map.get("commNumber");
        } else {
            commNumber = blog.getCommNumber();
        }
        if (map.get("forwardNumber") != null) {
            forwardNumber = (int) map.get("forwardNumber");
        } else {
            forwardNumber = blog.getForwardNumber();
        }
        long timer = Tools.getMS(blog.getBlogUpTime());
        double hot = Tools.getHotNumber(likeNumber, commNumber, forwardNumber, timer);
        map.put("_hot", String.valueOf(hot));
        blogMapper.UpdateBlog(map);
    }

    /**
     * @apiNote 查询热门博客
     */
    @Override
    public List<Blog> SelectBlogHot(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");

        Tools.isMapNull(map);

        int getPage = (int) map.get("getPage");
        getPage = (getPage - 1) * (int) map.get("getNumber");
        map.put("getPage", getPage);


        // 获取返回博文数组
        List<Blog> blogList = blogMapper.SelectBlogHot(map);
        if (request.getHeader("Authorization") != null && !(request.getHeader("Authorization").equals(""))) {
            parmMap.clear();
            parmMap.put("userId", Tools.getUserId(request));
            // 查询该用户点赞的博文
            List<BlogLike> likeInfo = blogMapper.SelectUserIsLike(parmMap);
            // 查询该用户的转发博文
            List<BlogRef> blogRefs = blogMapper.SelectBlogRef(parmMap);
            // 查询用户的关注列表
            List<Attention> attentions = blogMapper.SelectAttention(parmMap);
            return Tools.isBlogOpt(request, blogList, likeInfo, blogRefs, attentions);
        } else {
            return Tools.isBlogOpt(request, blogList);
        }

    }

    /**
     * @apiNote 查询最新发布的博客
     */
    @Override
    public List<Blog> SelectBlogNow(Map<String, Object> map) {
        // 获取请求操作
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);

        // 设置必要参数
        int getPage = (int) map.get("getPage");
        getPage = (getPage - 1) * (int) map.get("getNumber");
        map.put("getPage", getPage);
        // 获取返回博文数组
        List<Blog> blogList = blogMapper.SelectBlogNow(map);
        if (request.getHeader("Authorization") != null && !(request.getHeader("Authorization").equals(""))) {
            parmMap.clear();
            parmMap.put("userId", Tools.getUserId(request));
            // 查询该用户点赞的博文
            List<BlogLike> likeInfo = blogMapper.SelectUserIsLike(parmMap);
            // 查询该用户的转发博文
            List<BlogRef> blogRefs = blogMapper.SelectBlogRef(parmMap);
            // 查询用户的关注列表
            List<Attention> attentions = blogMapper.SelectAttention(parmMap);
            return Tools.isBlogOpt(request, blogList, likeInfo, blogRefs, attentions);
        } else {
            return Tools.isBlogOpt(request, blogList);
        }

    }

    /**
     * @apiNote 博客点赞
     */
    @Override
    public void LikeBlog(Map<String, Object> map) {
        String blogID = (String) map.get("blogId");
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        // map判空
        Tools.isMapNull(map);
        // 鉴权
        Tools.isLogin(request);
        // 数据操作
        // 数据表添加
        map.put("createTime", Tools.getTime());
        blogMapper.createBlogLike(map);
        Blog blogInfo = blogMapper.SelectBlog(blogID);
        int LikeNumber = blogInfo.getLikeNumber();
        String blogId = (String) map.get("blogId");
        map.clear();
        map.put("blogId", blogId);
        map.put("likeNumber", (LikeNumber + 1));
        map.put("request", request);
        UpdateBlog(map);
    }

    /**
     * @apiNote 取消点赞
     */
    @Override
    public void cancelLikeBlog(Map<String, Object> map) {
        String blogID = (String) map.get("blogId");
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        // map判空
        Tools.isMapNull(map);
        // 鉴权
        Tools.isLogin(request);
        // 数据操作
        // 数据表添加
        blogMapper.deleteBlogLike(map);
        Blog blogInfo = blogMapper.SelectBlog(blogID);
        int LikeNumber = blogInfo.getLikeNumber();
        map.clear();
        map.put("blogId", blogID);
        map.put("likeNumber", (LikeNumber - 1));
        map.put("request", request);
        UpdateBlog(map);
    }

    /**
     * @apiNote 查询单个博客的详细信
     */
    @Override
    public Blog selectBlogInfo(String blogID) {
        return blogMapper.SelectBlog(blogID);
    }

    /**
     * @apiNote 转发博文
     */
    @Override
    public void createRefBlog(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        // 判断map参数是否合法
        Tools.isMapNull(map);
        // 判断用户是否登录
        Tools.isLogin(request);
        // 获取用户ID
        map.put("blogUpTime", Tools.getTime());
        map.put("userID", Tools.getUserId(request));
        map.put("blogID", Tools.getUUID());
        map.put("type", '3');
        map.put("blogContent", EmojiParser.parseToAliases((String) map.get("blogContent")));
        blogMapper.CreateBlog(map);

        // 进行信息修改
        parmMap.clear();
        // 获取被转发的ID
        String blogID = (String) map.get("refwordUrl");
        Blog blog = blogMapper.SelectBlog(blogID);
        int refNumber = blog.getForwardNumber();
        refNumber += 1;
        parmMap.put("forwardNumber", refNumber);
        parmMap.put("blogID", blogID);
        blogMapper.UpdateBlog(parmMap);

        //进行map绑定
        parmMap.clear();
        parmMap.put("userId", Tools.getUserId(request));
        parmMap.put("blogId", blogID);
        parmMap.put("createTime", Tools.getTime());
        blogMapper.createRefBlog(parmMap);
    }

    /**
     * @apiNote 取消转发
     */
    @Override
    public void DeleteRefBlog(Map<String, Object> map) {
        HttpServletRequest request = (HttpServletRequest) map.get("request");
        map.remove("request");
        Tools.isMapNull(map);
        Tools.isLogin(request);
        String userId = Tools.getUserId(request);
        map.put("userId", userId);
        String blogID = (String) map.get("blogId");

        parmMap.clear();
        Blog blog = blogMapper.SelectBlog(blogID);
        int refNumber = blog.getForwardNumber();
        refNumber -= 1;
        parmMap.put("forwardNumber", refNumber);
        parmMap.put("blogID", blogID);
        blogMapper.UpdateBlog(parmMap);

        // 进行信息修改
        parmMap.clear();
        parmMap.put("blogId", blogID);
        parmMap.put("deleteTime", Tools.getTime());
        parmMap.put("userId", userId);
        parmMap.put("refwordUrl", blogID);
        blogMapper.DeleteBlog(parmMap);
        blogMapper.DeleteBlogRef(parmMap);
    }
}
